import "../pages/style/public.scss"
import Mix,{copyProperties} from './mix'
import { Base } from './compose/compose'
import { isType, randomId } from "./utils"

class Com extends Mix.mix(...Base){
  template = null
  root = null

  constructor( tplHandle , model = {} ){
    const args = Array.prototype.slice.call(arguments)
    super( tplHandle )
    this.init(...args)
    // this.initComEvents()
    const data = this.trigger('onBeforeTemplate', model )
    this.model = data ? data[0] : {}
    this.templateHandle = tplHandle
    this.template = this.templateHandle(this.model)
    this.trigger('onCreated')
  }

  init(){
    const args = Array.prototype.slice.call(arguments)
    this.constructor.__inits__ && this.constructor.__inits__.map( fn => { fn && fn.apply( this, args) })
    for(let key in this.constructor){
      if( key.indexOf('__inits_') === 0 && key != '__inits__' ){
        this.constructor[key] && this.constructor[key].map( fn => {
          fn && fn.apply( this, args)
        })
      }
    }
    
    this.constructor 
    && this.constructor.__decorators__ 
    && this.constructor.__decorators__.map(( dec )=>{
      dec( this )
    })
    
  }
  // 在目标el上渲染组件
  render( targetEl ){
    if (targetEl) {
      const before = this.trigger('onBeforeRender', this.template)
      this.template = before && before.get(0) ? before.get(0) : this.template
      this.template = isType(this.template, 'String') ? this.template : this.template.get(0).outerHTML
      this.root = $(this.template)
      $(targetEl).before( this.root )
      $(targetEl).remove()
      this.trigger('onRendered')
    }
  }

  appendBody(){
    const root = $('<div></div>')
    $('body').append(root)
    this.render( root )

    this._parent && this._parent.delChild( this )
    this._parent = null
  }
  // 将本组件移动到 指定父组件
  appendTo( parent , selector ){
    if(!parent.hasChild( this )){
      this._parent && this._parent.delChild( this )
      this._parent = parent
      parent.pushChild( this )

      const el = parent.getEl( selector )
      el && $(el).append( this.root )
    }
  }

  class( arr = [] ){
    if (this.root ){
      arr.map( cls => {
        $(this.root).addClass(cls)
      })
    }
  }

  static extend(...mixins){
    class reCls extends Com{
      constructor(){
        const args = Array.prototype.slice.call(arguments)
        super( ...args )
        for (let mixin of mixins) {
          // if( mixin.prototype && mixin.prototype.init ){
          //   inits.push( {fn: mixin.prototype.init , args})
          //   //delete mixin.prototype.init
          // }
          copyProperties(this, new mixin(...args), reCls); // 拷贝实例属性
        }
      }

      static _cls_id = 'cls_' + randomId()
    }

    // reCls.__inits_sub__ = []

    for (let mixin of mixins) {
      copyProperties(reCls, mixin); // 拷贝静态属性
      copyProperties(reCls.prototype, mixin.prototype, reCls, 'sub'); // 拷贝原型属性
    }
  
    return reCls
  }
}


export default Com